package com.newcore.ncimagepicker.nc_image_picker

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.media.ExifInterface
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import androidx.core.content.FileProvider
import java.io.*
import java.security.MessageDigest
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.HashMap
import android.util.*

fun uriToFilePath(context: Context, uri: Uri?): HashMap<String, Any>? {
    if(uri == null){
        return null
    }
    if ("file" == uri.scheme) {
        val res = hashMapOf<String, Any>()
        res["path"] = uri.path ?: ""
        return res
    } else {
        return filenameFromUri(context, uri)
    }
}

fun filenameFromUri(context: Context, uri: Uri): HashMap<String, Any> {
    val res: java.util.HashMap<String, Any>
    val filePath = getFilePathFromCursor(context, uri)
    res = if (filePath.isNullOrBlank()) {
        getFilePathFromInputStream(context, uri)
    } else {
        getInfoFromPath(filePath)
    }
    return res
}

fun getOrientationRotate(path: String) : Int {
    var degree = 0
    try {
        // 从指定路径下读取图片，并获取其Exif信息
        val exifInterface = ExifInterface(path);
        // 获取图片的旋转信息
        val orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
        if(orientation == ExifInterface.ORIENTATION_ROTATE_90)
            degree = 90
        else if(orientation == ExifInterface.ORIENTATION_ROTATE_180)
            degree = 180;
        else if(orientation == ExifInterface.ORIENTATION_ROTATE_270) {
            degree = 270;
        }
    } catch (e: IOException) {
        e.printStackTrace();
    }
    return degree;
}

fun getInfoFromPath(path: String) : HashMap<String, Any> {
    val res = hashMapOf<String, Any>()
    val opt = BitmapFactory.Options()
    opt.inJustDecodeBounds = true
    val bitmap = BitmapFactory.decodeFile(path, opt)
    res["width"] = opt.outWidth
    res["height"] = opt.outHeight
    res["path"] = path
    bitmap?.recycle()
    return res
}

private fun getFilePathFromCursor(context: Context, uri: Uri): String? {
    var filePath: String? = null
    var cursor: Cursor? = null
    try {
        val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
        cursor = context.contentResolver.query(uri, filePathColumn, null, null, null)
        cursor!!.moveToFirst()
        val columnIndex = cursor.getColumnIndex(filePathColumn[0])
        filePath = cursor.getString(columnIndex)
        cursor.close()
    } catch (e: Exception) {
        e.printStackTrace()
    } finally {
        cursor?.close()
    }
    return filePath
}

private fun getFilePathFromInputStream(context: Context, uri: Uri): HashMap<String, Any>{
    var filePath = ""
    var inputStream: InputStream? = null
    var res = hashMapOf<String, Any>()
    try {
        inputStream = context.contentResolver.openInputStream(uri)
        val bitmap = BitmapFactory.decodeStream(inputStream, null, getBitMapOptions(context, uri))
        inputStream!!.close()
        filePath = context.externalCacheDir?.absolutePath + md5(uri.toString())
        if(bitmap != null){
            res = saveBitmap(bitmap, File(filePath))
            res["path"] = filePath
        }
    } catch (e: Exception) {
        e.printStackTrace()
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }

        }
    }
    return res
}

fun getBitMapOptions(context: Context, uri: Uri): BitmapFactory.Options {

    var options = BitmapFactory.Options()
    options.inJustDecodeBounds = true
    val stream = context.contentResolver.openInputStream(uri)
    BitmapFactory.decodeStream(stream, null, options)
    stream!!.close()
    var width = options.outWidth
    var height = options.outHeight
    if (width > height) {
        val temp = width
        width = height
        height = temp
    }
    val sampleRatio = Math.max(width / 900, height / 1600)
    options = BitmapFactory.Options()
    options.inSampleSize = sampleRatio
    return options
}

fun saveBitmap(bitmap: Bitmap, file: File): HashMap<String, Any> {
    val map = hashMapOf<String, Any>()
    var fos: FileOutputStream? = null
    try {
        file.createNewFile()
        fos = FileOutputStream(file)

        map["height"] = bitmap.height
        map["width"] = bitmap.width
        bitmap.compress(Bitmap.CompressFormat.JPEG, 75, fos)
        fos.flush()
    } catch (e: FileNotFoundException) {
        e.printStackTrace()
    } catch (e: IOException) {
        e.printStackTrace()
    } finally {
        if (fos != null) {
            try {
                fos.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }
    return map
}
fun saveBitmap(bitmap: Bitmap, fileName: String, path: String): Boolean {
    val file = File(path)
    if (!file.exists()) {
        file.mkdir()
    }
    fileName.isNullOrBlank()
    val imageFile = File(file, fileName)
//    return saveBitmap(bitmap, imageFile)
    return true
}

fun md5(value: String): String {
    val instance: MessageDigest = MessageDigest.getInstance("MD5")
    //对字符串加密，返回字节数组
    val digest:ByteArray = instance.digest(value.toByteArray())
    var sb : StringBuffer = StringBuffer()
    for (b in digest) {
        //获取低八位有效值
        var i :Int = b.toInt() and 0xff
        //将整数转化为16进制
        var hexString = Integer.toHexString(i)
        if (hexString.length < 2) {
            //如果是一位的话，补0
            hexString = "0" + hexString
        }
        sb.append(hexString)
    }
    return sb.toString()
}

fun takePic(activity: Activity, saveDir: String,requestCode:Int) : File? {
    val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    if (takePictureIntent.resolveActivity(activity.packageManager) != null) {
        // Create the File where the photo should go
        var photoFile: File? = null
        try {
            photoFile = createImageFile(saveDir)
        } catch (ex: IOException) {
            ex.printStackTrace()
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            val uri: Uri
            uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                FileProvider.getUriForFile(activity,
                        activity.applicationContext.packageName + ".fileProvider", photoFile)
            } else {
                Uri.fromFile(photoFile)
            }
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
            activity.startActivityForResult(takePictureIntent, requestCode)
        }
        return photoFile;
    }
    return null
}

private fun createImageFile(saveDir: String): File? {
    val dir = File(saveDir)
    if (!dir.exists()) {
        dir.mkdirs()
    }

    // Create an image file name
    val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss",Locale.CHINA).format(Date())
    val imageFileName = "JPEG_" + timeStamp + "_"
    val storageDir = File(saveDir)
    return File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",  /* suffix */
            storageDir /* directory */
    )
}
